package org.ricks.log.pattern;

import java.util.Objects;

/**
 * @author chenwei
 * @Description:
 * @date 2023/1/916:55
 */
final class FormattingInfo {
    private static final char[] SPACES = new char[]{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '};
    private static final FormattingInfo DEFAULT = new FormattingInfo(false, 0);

    /**
     * 最小长度
     */
    private final int minLength;
    /**
     * 左对齐
     */
    private final boolean leftAlign;

    private FormattingInfo(final boolean leftAlign, final int minLength) {
        this.leftAlign = leftAlign;
        this.minLength = minLength;
    }

    public static FormattingInfo getDefault() {
        return DEFAULT;
    }

    public static FormattingInfo getOrDefault(boolean leftAlign, int minLength) {
        if (leftAlign == DEFAULT.leftAlign && minLength == DEFAULT.minLength) {
            return DEFAULT;
        } else {
            return new FormattingInfo(leftAlign, minLength);
        }
    }

    /**
     * 根据指定的长度和对齐方式调整缓冲区的内容
     *
     * @param startIndex 缓冲区起始位置
     * @param buffer     缓冲区
     */
    public void format(final int startIndex, final StringBuilder buffer) {
        final int rawLength = buffer.length() - startIndex;

        if (rawLength < minLength) {
            if (leftAlign) {
                final int fieldEnd = buffer.length();
                buffer.setLength(startIndex + minLength);

                for (int i = fieldEnd; i < buffer.length(); i++) {
                    buffer.setCharAt(i, ' ');
                }
            } else {
                int padLength = minLength - rawLength;

                final char[] paddingArray = SPACES;

                for (; padLength > paddingArray.length; padLength -= paddingArray.length) {
                    buffer.insert(startIndex, paddingArray);
                }

                buffer.insert(startIndex, paddingArray, 0, padLength);
            }
        }
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (!(o instanceof FormattingInfo)) {
            return false;
        }
        FormattingInfo that = (FormattingInfo) o;
        return minLength == that.minLength && leftAlign == that.leftAlign;
    }

    @Override
    public int hashCode() {
        return Objects.hash(minLength, leftAlign);
    }

    @Override
    public String toString() {
        return "FormattingInfo" +
                "[leftAlign=" +
                leftAlign +
                ", minLength=" +
                minLength +
                ']';
    }
}